<template>
  <div class="flow-chart">
    <a-spin :spinning="spinning" style="width: 100%; height: 100%" :class="{ 'bpm-x6chart-spin-box': spinning }">
      <div>
        <div class="flow-header">
          <span>流程名称：{{ flowName }}</span>
          <a-divider type="vertical" style="margin-left: 16px" />
          <a-button class="head-btn" type="link" @click="showHistory">查看响应历史</a-button>
          <a-divider type="vertical" style="margin-left: 16px" />
          <a-button class="head-btn" type="link" style="padding: 4px" @click="handleMaximize">最大化</a-button>
          <a-button class="head-btn" type="link" style="padding: 4px" @click="changeSize">
            {{ position == 'small' ? '展开' : '收起' }}
          </a-button>

          <span v-if="position" style="float: right; display: flex; align-items: center; height: 32px">
            <span class="step box" style="background-color: #b00015" />
            <span class="step">当前步骤</span>
            <span class="step box" style="background-color: #35b098" />
            <span class="step">已执行</span>
            <span class="step box" style="background-color: #98a0ac" />
            <span class="step">未执行</span>
          </span>
        </div>
        <div v-show="position == 'big'" v-if="!loadingCanvas" class="bpm-x6chart">
          <avic-flow-canvas
            ref="flowCanvas"
            :graph-option="graphOption"
            :data="flowData"
            @node-click="nodeClick"
            @user-defined-click="userDefinedClick"
          />
        </div>
        <div v-if="error" style="height: 100%; display: flex; align-items: center; margin-top: 20px">
          <avic-error-card :error-message="error" />
        </div>
        <ChartModal
          v-if="showMaxModal"
          :graph-option="graphOption"
          :flow-data="flowData"
          :flow-name="flowName"
          @close="showMaxModal = false"
        />
        <AvicModal
          :visible="openModal"
          title="配置的人员信息"
          width="800px"
          height="520px"
          :centered="true"
          :mask-closable="false"
          :footer="null"
          @cancel="openModal = false"
        >
          <a-list :data-source="nodeUserDefinedList">
            <template #renderItem="{ item }">
              <a-list-item>{{ item.userName }} （ {{ item.deptName }} ）</a-list-item>
            </template>
          </a-list>
        </AvicModal>
      </div>
    </a-spin>
  </div>
  <!--子流程图-->
  <avic-bpm-chart-child :deployment-id="deploymentIdChild" :select-visible="selectVisibleChild" @closeChild="closeChild" />
  <!--子流程流程跟踪--->
  <father-track
    :title="fatherTitle"
    :show-bpm-open-form-but="showBpmOpenFormBut"
    :entry-id="fatherEntryId"
    :visible="fatherVisible"
    @closeFather="closeFather"
  />
  <sub-flow-list v-if="subListVisible" :sub-data="subList" @close="closeSubFlow" @confirm="selectSubFlow" />
  <historyModal v-if="showHistroyModal" :entry-id="entryId" @close="showHistroyModal = false" />
  <newestModal v-if="showNewestModal" :entry-id="entryId" :flow-data="flowData" @close="showNewestModal = false" />
</template>
<script>
import { Spin } from 'ant-design-vue';
import AvicBpmChartChild from '../bpm-content/AvicBpmChartChild/index.vue';
import AvicBpmFlowCanvas from '@/views/avic/bpm/flowdetail/components/bpm-flow-canvas/index.vue';
import AvicErrorCard from '@/components/error-card/index.vue';
import { httpAction } from '@/api/avic/bpm/FlowUtilApi';
import ChartModal from './chartModal.vue';
import historyModal from './historyModal.vue';
import newestModal from './newestModal.vue';
import FatherTrack from '../bpm-buttons-modal/FatherTrack.vue';
import SubFlowList from '../bpm-buttons-modal/SubFlowList.vue';
export default {
  name: 'AvicBpmFlowChartTemplate',
  components: {
    ASpin: Spin,
    AvicFlowCanvas: AvicBpmFlowCanvas,
    AvicErrorCard,
    ChartModal,
    historyModal,
    newestModal,
    FatherTrack,
    SubFlowList,
    AvicBpmChartChild
  },
  props: {
    // 流程图加载参数 ,包括 url 请求地址  parameter 加载参数 method 请类型
    flowParam: {
      type: Object,
      required: true,
      default: null
    },
    position: {
      type: String,
      default: null
    },
    // 点击流程节点类型
    type: {
      type: String,
      required: false,
      default: null
    },
    showBpmOpenFormBut: {
      type: Boolean,
      required: false,
      default: true
    }
  },
  emits: ['changeSize'],
  data() {
    return {
      spinning: false,
      graphOption: {
        panning: false, // 打开拖动
        grid: false
      },
      error: '',
      data: null,
      flowData: {},
      instanceData: {},
      loadingCanvas: false,
      showMaxModal: false,
      showHistroyModal: false,
      showNewestModal: false,
      flowName: null, // 流程名称
      popoverData: [],
      selectTabKey: null,
      startExecutionId: '', // 流程跳转
      fatherVisible: false, // 子流程状态
      fatherEntryId: '', // 子流程id
      subListVisible: false, // 子流程列表状态
      subList: [], // 子表列表
      subprocess: [],
      fatherTitle: '',
      deploymentIdChild: '', // 字流程 deploymentId
      chartHeight: '300px',
      selectVisibleChild: false, // 子流程 是否显示
      openModal: false,
      nodeUserDefinedList: []
    };
  },
  computed: {
    entryId() {
      return this.flowParam.parameter.processInstanceId || '';
    }
  },
  watch: {
    flowParam: {
      deep: true,
      immediate: true,
      handler() {
        this.refreshFlowChart();
      }
    }
  },
  mounted() {
    // setTimeout(() => {
    //   this.refreshFlowChart();
    // }, 100);
  },
  methods: {
    changeSize() {
      this.$emit('changeSize', this.position === 'small' ? 'open' : 'close');
    },
    handleMaximize() {
      this.showMaxModal = true;
    },
    // 刷新流程图
    async refreshFlowChart() {
      this.spinning = true;
      if (this.flowParam && this.flowParam.parameter && this.flowParam.url) {
        this.$emit('beforeLoadFlowChart', this.flowParam);
        this.loadDataProcessJson();
      }
    },
    // 加载流程数据
    loadDataProcessJson() {
      this.loadingCanvas = true;
      httpAction(this.flowParam.url, this.flowParam.parameter)
        .then((res) => {
          if (res.success === true) {
            this.data = res.data;
            this.instanceData = res.data;
            this.drawChart(res.data);
            if (res.data && res.data.subprocess) {
              this.subprocess = res.data.subprocess;
            }
            this.error = '';
          } else {
            this.error = '流程加载失败';
          }
          this.spinning = false;
        })
        .catch((e) => {
          console.error(e);
          this.error = '流程加载失败';
          this.spinning = false;
        });
    },
    // 画图
    drawChart(result) {
      const { creator, processModel, currActivities, histActivities, historyLines, processAssignee } = result;
      const { edge, graph, node } = processModel;
      node.forEach((item) => {
        item.data.entryId = this.entryId; // 存入实例id 获取节点的流程处理信息
        item.data.creator = creator;
        item.data.nodeStatus = 'norun';
        item.data.nodeBorderStatus = '';
        item.data.userText = '--';
        item.data.userEndTime = '--';
        item.data.userConsumeTime = '--';
        item.data.activityDate = '--';
        item.data.activityAssigneeUser = processAssignee[`${item.data.name}_reasonableFinishTime`] || '--';
        if (processAssignee && processAssignee[item.data.name]) {
          item.data.userText = processAssignee[item.data.name]; // 响应人
          item.data.activityAssigneeUser = processAssignee[item.data.name];
        }

        if (processAssignee && processAssignee[`${item.data.name}_endTime`]) {
          item.data.userEndTime = processAssignee[`${item.data.name}_endTime`]; // 响应时间
          item.data.activityDate = processAssignee[`${item.data.name}_endTime`];
        }

        if (processAssignee && processAssignee[`${item.data.name}_consumeTime`]) {
          item.data.userConsumeTime = processAssignee[`${item.data.name}_consumeTime`]; // 响应周期
        }

        // 运行过
        if (histActivities && histActivities.includes(item.data.name)) {
          item.data.nodeStatus = 'over';
          item.data.showTooltipName = item.data.name;
        }
        // 运行中
        if (currActivities && currActivities.includes(item.data.name)) {
          item.data.nodeStatus = 'run';
          item.data.showTooltipName = item.data.name;
        }
        if (historyLines && historyLines[0] && historyLines[0].split(',')[1] === item.data.name) {
          item.data.isBeginTask = true;
        }
        if (['over', 'run', 'subrun'].includes(item.data.nodeStatus)) {
          // eslint-disable-next-line prefer-destructuring
          item.data.popoverData = this.popoverData.filter((node) => node.activityName === item.data.name)[0];
        }
      });
      edge.forEach((item) => {
        const line = [];
        node.forEach((tim) => {
          if (tim.id === item.source.cell) {
            line.unshift(tim.data.name);
          } else if (tim.id === item.target.cell) {
            line.push(tim.data.name);
          }
        });
        if (historyLines && historyLines.includes(line.join(','))) {
          item.data.edgeStatus = 'run';
          // 设置运行中的箭头为橙色
          if (currActivities && currActivities.includes(line[1])) {
            item.data.edgeStatus = 'running';
          }
        } else {
          item.data.edgeStatus = 'norun';
        }
      });
      // 将模板图中没有的流转线加到实例图的edge集合
      historyLines &&
        historyLines.forEach((item) => {
          if (item && item.split(',').length === 2) {
            const linePoints = item.split(',');
            const sourceNode = linePoints[0];
            const targetNode = linePoints[1];
            let sourceNodeId = '';
            let targetNodeId = '';
            const jumpLineNodes = [];
            node.forEach((flowNode) => {
              if (flowNode.data.name === sourceNode) {
                sourceNodeId = flowNode.id;
                jumpLineNodes.unshift(flowNode);
              }
              if (flowNode.data.name === targetNode) {
                targetNodeId = flowNode.id;
                jumpLineNodes.push(flowNode);
              }
            });
            // 校验模板图中有没有的流转线
            // eslint-disable-next-line max-len
            const currentLine = edge.find(
              (templateEdge) => templateEdge.source.cell === sourceNodeId && templateEdge.target.cell === targetNodeId
            );
            if (!currentLine) {
              edge.push({
                shape: 'edge',
                vertices: [],
                source: {
                  cell: sourceNodeId
                  // port: sourcePort
                },
                target: {
                  cell: targetNodeId
                  // port: targetPort
                },
                data: {
                  edgeStatus: 'jump'
                },
                router: {
                  name: 'manhattan'
                }
              });
            }
          }
        });
      this.flowData = { edge, graph, node };
      this.flowName = graph.data.name;
      this.loadingCanvas = false;
      this.$nextTick(() => {
        if (this.$refs.flowCanvas) {
          this.$refs.flowCanvas.initFlow(this.flowData);
        }
      });
    },
    setStartPosition(pos) {
      if (this.$refs.flowCanvas) {
        this.$refs.flowCanvas.setStartPosition(pos);
      }
      if (this.$refs.childFlowCanvas) {
        this.$refs.childFlowCanvas.setStartPosition(pos);
      }
    },
    showHistory() {
      this.showHistroyModal = true;
    },
    showNewest() {
      this.showNewestModal = true;
    },
    // 节点点击事件
    nodeClick({ node }) {
      // this.hovered = false;
      this.childClick(node);
      this.drawAct(this.flowParam.parameter.processInstanceId, node);
    },
    userDefinedClick({ node }) {
      this.nodeUserDefinedList = node.data.userDefinedList ? JSON.parse(node.data.userDefinedList) : [];
      this.openModal = true;
    },
    // 子流程点击事件
    childClick(node) {
      const child = node.store.data;

      if (child.data.nodeType === 'subprocess' || ['subrun', 'subover'].includes(child.data.nodeStatus)) {
        if (this.subprocess) {
          if (this.subprocess[child.data.name]) {
            if (this.subprocess[child.data.name].entryId) {
              this.fatherVisible = true;
              this.fatherEntryId = this.subprocess[child.data.name].entryId;
            } else if (this.subprocess[child.data.name].length > 1) {
              this.subListVisible = true;
              this.subList = this.subprocess[child.data.name];
            } else if (this.subprocess[child.data.name].length > 0 && this.subprocess[child.data.name][0].entryId) {
              this.fatherTitle = '子流程';
              this.fatherVisible = true;
              this.fatherEntryId = this.subprocess[child.data.name][0].entryId;
            } else if (child.store.data.deploymentId) {
              this.deploymentIdChild = child.data.deploymentId;
              this.selectVisibleChild = true;
            }
          } else {
            if (child.deploymentId) {
              this.deploymentIdChild = child.data.deploymentId;
              this.selectVisibleChild = true;
            }
          }
        } else if (child.deploymentId) {
          this.deploymentIdChild = child.data.deploymentId;
          this.selectVisibleChild = true;
        }
      }
    },
    closeChild() {
      this.selectVisibleChild = false;
    },
    closeFather() {
      this.fatherVisible = false;
      this.fatherEntryId = '';
    }
  }
};
</script>
<style lang="less" scoped>
.main {
  border: 1px solid #d6dce3;
}
.flow-chart {
  // height: 100%;
  width: 100%;
  // border-top: 1px solid #C9CDD4;
  border: 1px solid #c9cdd4;
  border-radius: 0px;
  box-sizing: content-box;
  // margin: 0px 12px 12px;
}
.bpm-x6chart-spin-box {
  // height: 100%;
}
.ant-spin-nested-loading {
  // height: 100%;
}
:deep(.ant-spin-container) {
  // height: 100% !important;
  > div {
    // height: 100% !important;
  }
}
.bpm-x6chart {
  height: calc(100% - 40px);
  width: 100%;
  // overflow: auto;
  // background-color: #f8f9fa;
  // background-color: #ffffff;
  // overflow: auto;
  border-radius: 0px 0px 6px 6px;
  :deep(.x6-graph-scroller) {
    // overflow: visible !important;
    height: initial !important;
    max-height: 320px;
    .x6-graph {
      box-shadow: none;
    }
  }
}
.flow-header {
  padding: 4px 12px;
  line-height: 32px;
  height: 40px;
  background: #f8f8f8;
  border-bottom: 1px solid #dde2e6;
  border-radius: 0;
  span {
    // font-weight: 600;
    font-size: 14px;
  }
  .head-btn {
    padding: 0;
    color: #4e5969;
    &:hover {
      color: @primary-color;
    }
  }
}
.ant-btn-text:not(:disabled):hover {
  background: none;
}
.step {
  height: 14px;
  line-height: 1;
  display: inline-block;
  margin-left: auto;
  margin-right: 10px;
  cursor: default;
  &.box {
    width: 14px;
    margin-right: 5px;
  }
}
</style>
